#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
    // at Windows, must call this sdk-api at first.
    HS_HTTP_Startup();
    connect(this, SIGNAL(signals_HttpCallBackMessage_Batch(uint, void *, void *)), SLOT(DealHttpCallBackMsg_Batch(uint, void *, void *)));
    rtsDlg = NULL;
    pbsDlg = NULL;
}

MainWindow::~MainWindow() {
    HS_HTTP_Cleanup ();
    delete ui;
}

void MainWindow::init() {
    // just a sample demo
    ui->ed_ip->setText("172.18.193.75");
    ui->ed_port->setText("80");
    ui->ed_usr->setText("admin");
    ui->ed_psw->setText("admin123");
    ui->ed_url->setText("/api/video/video-encode");
    ui->ed_data->setText("{\"action\":\"get\"}");
    ui->cb_post->setChecked(true);

}

void MainWindow::on_pushButton_clicked() {
    if (m_HttpContext[0].pMyHandle != NULL) {
        HS_HTTP_Logout(m_HttpContext[0].pMyHandle);
        m_HttpContext[0].pMyHandle = NULL;
    }
    QString ip,usr,psw,port;
    ip = ui->ed_ip->text();
    usr = ui->ed_usr->text();
    psw = ui->ed_psw->text();
    port = ui->ed_port->text();

    // please checked the decive is suport use the sdk at first.
    auto bSuport = HS_HTTP_CheckSupport (ip.toStdString ().c_str (), port.toInt ());

    if (!bSuport) {
        showMsg(tr("The Device can't use this sdk."));
        return;
    }

    HS_HTTP_INFO info;
    memset(&info, 0, sizeof(HS_HTTP_INFO));
    memcpy(info.cIpAddress,ip.toStdString().c_str(), ip.size());
    memcpy(info.cUsername, usr.toStdString().c_str(), usr.size());
    memcpy(info.cPassword, psw.toStdString().c_str(), psw.size());
    info.nPort = port.toInt();
    info.nConnecttime = 1000;    // 500 mesc
    info.nSendtime = 500;
    info.nRecvtime = 500;
    info.msgFun = HttpMsgCallBack_Batch;
    info.nTryInterval = 200;
    info.nTryNum = 3;
    m_HttpContext[0].pHwnd = this;
    m_HttpContext[0].index = 0;
    info.lpContext = (void*)(&m_HttpContext[0]);
    qDebug() << "dev ip:" << info.cIpAddress;
    qDebug() << "dev usr:" << info.cUsername;
    qDebug() << "dev psw:" << info.cPassword;
    qDebug() << "dev ip:" << info.nPort;
    m_HttpContext[0].pMyHandle = HS_HTTP_Login(&info);
    return;
}

void MainWindow::HttpMsgCallBack_Batch(void *handle, long msgType, void *lpStruct, void *lpContext) {
    HTTP_LOGIN_CONTEXT *pContext = (HTTP_LOGIN_CONTEXT *)lpContext;
    MainWindow *ptr = (MainWindow *)pContext->pHwnd;
    if (msgType == HS_HTTP_MSG_LOGINOK) {
        emit ptr->signals_HttpCallBackMessage_Batch(msgType, pContext, lpStruct);
    } else if (msgType == HS_HTTP_MSG_LOGINFAIL) {
        emit ptr->signals_HttpCallBackMessage_Batch(msgType, pContext, lpStruct);
    } else if (msgType == HS_HTTP_MSG_NOCONNECT) {
        emit ptr->signals_HttpCallBackMessage_Batch(msgType, pContext, lpStruct);
    } else if (msgType == HS_HTTP_MSG_UPLOADFILE_FAIL) {
        emit ptr->signals_HttpCallBackMessage_Batch(msgType, pContext, lpStruct);
    } else if (msgType == HS_HTTP_MSG_UPLOADFILE_PERCENT) {
        int *pos = (int *)lpStruct;
        pContext->nUpgradePer = *pos;
        emit ptr->signals_HttpCallBackMessage_Batch(msgType, pContext, lpStruct);
    }
}

void MainWindow::on_pb_send_clicked(){
    if (m_HttpContext[0].pMyHandle == NULL) {
        showMsg(tr("Please login first!"));
        return;
    }
    QString url = this->ui->ed_url->text();
    QString json = this->ui->ed_data->text();

    HS_HTTP_CALL_PARAM param;
    memset(&param, 0, sizeof(HS_HTTP_CALL_PARAM));
    memcpy(param.cUrl, url.toStdString().c_str(), url.size());
    param.nPost = 1;

    char tmpBuf[40960] = {0};
    memcpy(tmpBuf, json.toUtf8 ().data (), json.toUtf8 ().size());
    param.cJsonData = tmpBuf;
    qDebug() << param.cJsonData;
    char *ret = NULL;
    auto nRet = HS_HTTP_Call(m_HttpContext[0].pMyHandle, &param, &ret);
    if (nRet) {
        qDebug() << strlen(ret);
        QString text(ret);
        this->ui->ed_res->setText(text);
        // use the sdk-api free ret pointer.
        HS_HTTP_FreeCallBuf(ret);
    } else {
        this->ui->ed_res->setText(tr("request fail!"));
    }
}

void MainWindow::DealHttpCallBackMsg_Batch(uint msg, void *lpContext, void *lpStruct) {
    int devInd = ((HTTP_LOGIN_CONTEXT *)lpContext)->index;
    QString strDevInd = QString::number(devInd);
    if (msg == HS_HTTP_MSG_LOGINOK) {
        showMsg(QString("Device index:%1  :  login success!").arg(strDevInd));
    } else if (msg == HS_HTTP_MSG_LOGINFAIL) {
        showMsg(QString("Device index:%1  :  password error!").arg(strDevInd));
    } else if (msg == HS_HTTP_MSG_NOCONNECT) {
        showMsg(QString("Device index:%1  :  not connect!").arg(strDevInd));
    } else if (msg == HS_HTTP_MSG_UPLOADFILE_FAIL) {
        showMsg(QString("Device index:%1  :  upload fial!").arg(strDevInd));
    } else if (msg == HS_HTTP_MSG_UPLOADFILE_PERCENT) {
        QString strPer = QString::number(((HTTP_LOGIN_CONTEXT *)lpContext)->nUpgradePer);
        this->ui->ed_res->setText(QString("Device index:%1  :  upload percent:%2").arg(strDevInd).arg(strPer));
    }
}

void MainWindow::showMsg(QString text) {
    QMessageBox msg;
    msg.setText(text);
    msg.exec();
}


void MainWindow::on_pb_browse_clicked(){
    QFileDialog file;
    file.setOption(QFileDialog::DontUseNativeDialog);

    QString selectedFilter;
    QString fileName = file.getOpenFileName(this, tr("Open"), "", tr("All(*.*);;\
                                               PACKAGE(*.package);;\
                                               FLS(*.FLS)"),
                                                &selectedFilter);
    ui->ed_upgradefile->setText(fileName);
}

void MainWindow::on_pb_upgrade_clicked() {
    if (m_HttpContext[0].pMyHandle == NULL) {
        showMsg(tr("please login first!"));
        return;
    }
    QString filepath = this->ui->ed_upgradefile->text();
    char *cfile = new char[512];
    memset(cfile, 0, 512);
    memcpy(cfile, filepath.toStdString().c_str(), filepath.toStdString ().size ());
/*
#if 1
    // by asyn, upload percent will through callback funtion show 'HS_HTTP_MSG_UPLOADFILE_PERCENT'
    HS_HTTP_Upgrade(m_HttpContext[0].pMyHandle, cfile, true);
#else
    // by sync, the call will return upload status
    auto bSuccess = HS_HTTP_Upgrade(m_HttpContext[0].pMyHandle, cfile, false);
    if (bSuccess) {
        showMsg ("Upload Success");
    } else {
        showMsg ("Upload Failed");
    }
#endif
*/
/*
 * or use this way,also can upload file
    // "/api/upgrade/upgrade-file" ,upgrade api
    HS_HTTP_UploadFile(m_HttpContext[0].pMyHandle, "/api/upgrade/upgrade-file", cfile, true);
*/
    char *recvBuf = NULL;
    auto ret = HS_HTTP_UploadFile(m_HttpContext[0].pMyHandle, "/api/upgrade/upgrade-file", cfile, &recvBuf, false);
    if (ret) {
        QString tt = recvBuf;
        HS_HTTP_FreeCallBuf (recvBuf);
        this->ui->ed_res->setText(tt);
    }
    delete cfile;
    cfile = NULL;
}

void MainWindow::on_pb_logout_clicked() {
    if (m_HttpContext[0].pMyHandle != NULL) {
        HS_HTTP_Logout(m_HttpContext[0].pMyHandle);
        m_HttpContext[0].pMyHandle = NULL;
    }
}

void MainWindow::on_pb_rts_clicked() {
    if (!m_HttpContext[0].pMyHandle) {
        showMsg (tr("Please login at first!"));
        return;
    }
    if (rtsDlg) {
        delete rtsDlg;
        rtsDlg = NULL;
    }
    int nChannel = ui->ed_rts_channel->text ().toInt ();
    int nStream = ui->ed_rts_stream->text ().toInt ();
    rtsDlg = new RTSDialog();
    rtsDlg->setParam (m_HttpContext[0].pMyHandle, nChannel, nStream, 1);
    rtsDlg->show ();
}

void MainWindow::on_pb_pbs_clicked()
{
    if (!m_HttpContext[0].pMyHandle) {
        showMsg (tr("Please login at first!"));
        return;
    }
    TmpInfo info;
    info.nChannel = ui->ed_pbs_channel->text ().toInt ();
    info.nStream = ui->ed_pbs_stream->text ().toInt ();
    info.nSound = 1;
    info.nStartTime = ui->ed_pbs_starttime->text ().toInt ();
    info.nEndTime = ui->ed_pbs_endtime->text ().toInt ();
    info.nFileType = ui->ed_pbs_filetype->text ().toInt ();
    info.nSpeed = ui->ed_pbs_speed->text ().toInt ();
    info.hClientHandle = m_HttpContext[0].pMyHandle;

    pbsDlg = new PBSDialog();
    pbsDlg->setParam (info);
    pbsDlg->show ();
}

void MainWindow::on_pb_opentalk_clicked()
{
    if (!m_HttpContext[0].pMyHandle) {
        showMsg (tr("Please login at first!"));
        return;
    }
    HS_HTTP_OpenTalk (m_HttpContext[0].pMyHandle);
}

void MainWindow::on_pb_closetalk_clicked()
{
    if (!m_HttpContext[0].pMyHandle) {
        showMsg (tr("Please login at first!"));
        return;
    }
    HS_HTTP_CloseTalk (m_HttpContext[0].pMyHandle);
}

void MainWindow::on_pb_testSend_clicked()
{
    QString url = this->ui->ed_url->text();
    QString json = this->ui->ed_data->text();

    QFuture<void> f = QtConcurrent::run([=](){
        for (int i = 0; i < 1000; i++) {
            HS_HTTP_CALL_PARAM param;
            memset(&param, 0, sizeof(HS_HTTP_CALL_PARAM));
            memcpy(param.cUrl, url.toStdString().c_str(), url.size());
            param.nPost = 1;
            char tmpBuf[40960] = {0};
            memcpy(tmpBuf, json.toStdString().c_str(), json.size());
            param.cJsonData = tmpBuf;
            char *ret = NULL;
            bool bSuccess = HS_HTTP_Call(m_HttpContext[0].pMyHandle, &param, &ret);

            qDebug() << "Loop:" << i << ", res:" << bSuccess;
            if (bSuccess){HS_HTTP_FreeCallBuf(ret);}
        }
    });
}

void MainWindow::runTest () {

    QString url = this->ui->ed_url->text();
    QString json = this->ui->ed_data->text();
    HS_HTTP_CALL_PARAM param;
    memset(&param, 0, sizeof(HS_HTTP_CALL_PARAM));
    memcpy(param.cUrl, url.toStdString().c_str(), url.size());
    param.nPost = 1;

    char tmpBuf[40960] = {0};
    memcpy(tmpBuf, json.toStdString().c_str(), json.size());
    param.cJsonData = tmpBuf;
    qDebug() << param.cJsonData;
    char *ret = NULL;
    auto nRet = HS_HTTP_Call(m_HttpContext[0].pMyHandle, &param, &ret);
    if (nRet) {
        qDebug() << strlen(ret);
        QString text(ret);
        this->ui->ed_res->setText(text);
        HS_HTTP_FreeCallBuf(ret);
    } else {
        this->ui->ed_res->setText(tr("request fail!"));
    }
}
